// Package repository provides reconciliation data persistence and queries.
package repository

import (
	"context"
	"time"

	"github.com/we-pay-kit/we-pay-kit/internal/db"
)

type ReconciliationData struct {
	ID                     int64
	ReconciliationDate     time.Time
	TotalTransactionCount  int
	TotalTransactionAmount float64
	TotalDiscountAmount    float64
	TotalActualPayAmount   float64
	ReconStatus            string
	DifferenceDesc         *string
	CreatedAt              time.Time
	UpdatedAt              time.Time
}

type ReconciliationRepository struct{ db *db.DB }

func NewReconciliationRepository(database *db.DB) *ReconciliationRepository {
	return &ReconciliationRepository{db: database}
}

func (r *ReconciliationRepository) Upsert(ctx context.Context, d ReconciliationData) error {
	q := `INSERT INTO reconciliation_data(reconciliation_date, total_transaction_count, total_transaction_amount, total_discount_amount, total_actual_pay_amount, recon_status)
          VALUES($1,$2,$3,$4,$5,$6)
          ON CONFLICT (reconciliation_date) DO UPDATE SET total_transaction_count=EXCLUDED.total_transaction_count,
            total_transaction_amount=EXCLUDED.total_transaction_amount,
            total_discount_amount=EXCLUDED.total_discount_amount,
            total_actual_pay_amount=EXCLUDED.total_actual_pay_amount,
            recon_status=EXCLUDED.recon_status,
            updated_at=now()`
	_, err := r.db.ExecContext(ctx, q, d.ReconciliationDate, d.TotalTransactionCount, d.TotalTransactionAmount, d.TotalDiscountAmount, d.TotalActualPayAmount, d.ReconStatus)
	return err
}

func (r *ReconciliationRepository) GetByDate(ctx context.Context, date time.Time) (*ReconciliationData, error) {
	q := `SELECT id, reconciliation_date, total_transaction_count, total_transaction_amount, total_discount_amount, total_actual_pay_amount, recon_status, difference_desc, created_at, updated_at
          FROM reconciliation_data WHERE reconciliation_date=$1`
	row := r.db.QueryRowContext(ctx, q, date)
	var d ReconciliationData
	var diff *string
	if err := row.Scan(&d.ID, &d.ReconciliationDate, &d.TotalTransactionCount, &d.TotalTransactionAmount, &d.TotalDiscountAmount, &d.TotalActualPayAmount, &d.ReconStatus, &diff, &d.CreatedAt, &d.UpdatedAt); err != nil {
		return nil, err
	}
	d.DifferenceDesc = diff
	return &d, nil
}
